"""
日志工具模块
"""
import logging
import uuid
from functools import wraps
from flask import request, g, has_request_context, has_app_context
import time
import traceback
from typing import Optional, Callable, Dict, Any
import socket
import platform
import os

class RequestIdFilter(logging.Filter):
    """请求ID过滤器，为每条日志添加请求ID和上下文信息"""
    
    def __init__(self):
        super().__init__()
        self.hostname = socket.gethostname()
        self.pid = os.getpid()
        self.platform = platform.platform()
    
    def filter(self, record):
        # 添加基础信息
        record.hostname = self.hostname
        record.process_id = self.pid
        record.platform = self.platform
        
        # 检查是否在请求或应用上下文中
        if has_request_context():
            record.request_id = getattr(g, 'request_id', 'No-Request-ID')
            record.url = request.url
            record.method = request.method
            record.remote_addr = request.remote_addr
            record.user_agent = request.headers.get('User-Agent', 'Unknown')
        else:
            record.request_id = 'No-Context'
            record.url = None
            record.method = None
            record.remote_addr = None
            record.user_agent = None
        
        return True

def generate_request_id() -> str:
    """生成请求ID，包含时间戳和随机数"""
    timestamp = int(time.time() * 1000)
    random_uuid = uuid.uuid4().hex[:12]
    return f"{timestamp}-{random_uuid}"

def log_request_info(logger: logging.Logger) -> Callable:
    """记录请求信息的装饰器，包含更多上下文信息和性能指标"""
    def decorator(f: Callable) -> Callable:
        @wraps(f)
        def wrapped(*args, **kwargs):
            if not has_request_context():
                return f(*args, **kwargs)
            
            # 生成并存储请求ID
            request_id = generate_request_id()
            g.request_id = request_id
            
            # 记录请求开始
            start_time = time.time()
            start_memory = get_memory_usage()
            
            # 构建请求信息
            request_info = {
                'request_id': request_id,
                'url': request.url,
                'method': request.method,
                'remote_addr': request.remote_addr,
                'user_agent': request.headers.get('User-Agent'),
                'start_time': start_time,
                'start_memory': start_memory
            }
            
            # 记录请求信息
            logger.info(f"Request started: {request.method} {request.url}", extra=request_info)
            
            try:
                # 记录请求体（如果存在）
                if request.is_json:
                    logger.debug("Request JSON", extra={
                        'request_id': request_id,
                        'json_data': request.get_json(silent=True)
                    })
                elif request.form:
                    logger.debug("Request Form", extra={
                        'request_id': request_id,
                        'form_data': dict(request.form)
                    })
                
                # 执行视图函数
                response = f(*args, **kwargs)
                
                # 计算性能指标
                duration = round((time.time() - start_time) * 1000, 2)
                memory_used = get_memory_usage() - start_memory
                
                # 构建响应信息
                response_info = {
                    'request_id': request_id,
                    'duration_ms': duration,
                    'memory_used_mb': round(memory_used / 1024 / 1024, 2),
                    'status_code': getattr(response, 'status_code', None)
                }
                
                # 记录响应信息
                logger.info(
                    f"Request completed: {request.method} {request.url}",
                    extra=response_info
                )
                
                return response
                
            except Exception as e:
                # 计算错误发生时的性能指标
                duration = round((time.time() - start_time) * 1000, 2)
                memory_used = get_memory_usage() - start_memory
                
                # 构建错误信息
                error_info = {
                    'request_id': request_id,
                    'error_type': e.__class__.__name__,
                    'error_message': str(e),
                    'duration_ms': duration,
                    'memory_used_mb': round(memory_used / 1024 / 1024, 2),
                    'traceback': traceback.format_exc()
                }
                
                # 记录错误信息
                logger.error(
                    f"Request failed: {request.method} {request.url}",
                    extra=error_info,
                    exc_info=True
                )
                raise
            
        return wrapped
    return decorator

class RequestLogger:
    """增强的请求日志记录器"""
    
    def __init__(self, logger: logging.Logger):
        self.logger = logger
        self.start_time = None
        self.start_memory = None
    
    def start_request(self, request_data: Optional[Dict] = None) -> None:
        """开始记录请求"""
        if not has_request_context():
            return
            
        self.start_time = time.time()
        self.start_memory = get_memory_usage()
        
        request_info = {
            'request_id': getattr(g, 'request_id', 'No-Request-ID'),
            'start_time': self.start_time,
            'start_memory': self.start_memory
        }
        
        if request_data:
            request_info['request_data'] = request_data
            
        self.logger.info(f"Request started: {request.method} {request.url}", extra=request_info)
    
    def end_request(self, response_data: Optional[Dict] = None, 
                   status_code: int = 200) -> None:
        """结束记录请求"""
        if not self.start_time:
            return
            
        duration = round((time.time() - self.start_time) * 1000, 2)
        memory_used = get_memory_usage() - self.start_memory
        
        response_info = {
            'request_id': getattr(g, 'request_id', 'No-Request-ID'),
            'duration_ms': duration,
            'memory_used_mb': round(memory_used / 1024 / 1024, 2),
            'status_code': status_code
        }
        
        if response_data:
            response_info['response_data'] = response_data
            
        self.logger.info(
            f"Request completed: {request.method} {request.url}",
            extra=response_info
        )
    
    def log_error(self, error: Exception) -> None:
        """记录错误信息"""
        if not self.start_time:
            return
            
        duration = round((time.time() - self.start_time) * 1000, 2)
        memory_used = get_memory_usage() - self.start_memory
        
        error_info = {
            'request_id': getattr(g, 'request_id', 'No-Request-ID'),
            'error_type': error.__class__.__name__,
            'error_message': str(error),
            'duration_ms': duration,
            'memory_used_mb': round(memory_used / 1024 / 1024, 2),
            'traceback': traceback.format_exc()
        }
        
        self.logger.error(
            f"Request failed: {request.method} {request.url}",
            extra=error_info,
            exc_info=True
        )

def setup_logger(name: str) -> logging.Logger:
    """设置增强的日志记录器"""
    logger = logging.getLogger(name)
    
    # 添加请求ID过滤器
    request_filter = RequestIdFilter()
    logger.addFilter(request_filter)
    
    return logger

def get_memory_usage() -> float:
    """获取当前进程的内存使用情况"""
    try:
        import psutil
        process = psutil.Process(os.getpid())
        return process.memory_info().rss
    except ImportError:
        return 0.0 